package studio7Omega.dao;


import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import studio7Omega.excepcion.DAOExcepcion;
import studio7Omega.modelo.Alquiler;
import studio7Omega.modelo.DetalleAlquiler;
import studio7Omega.modelo.Item;
import studio7Omega.modelo.Sala;
import studio7Omega.util.ConexionBD;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

public class AlquilerDAO extends BaseDAO{

	public int realizarReserva(Alquiler alq) throws DAOExcepcion{
		SimpleDateFormat formatoDelTexto = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println("AlquilerDAO: insertar(Alquiler alquiler)");
		String query = "INSERT INTO alquiler(idalquiler, fecha, horainicio, horafin, idusuario, idsala) VALUES (?,?,?,?,?,?)";
		String queryInsDet = "INSERT INTO detallealquiler(idalquiler,iditem,costo,adicional) VALUES (?,?,?,?)";
		String queryIndex="select max(idalquiler) from alquiler";
		String queryDetalle="select salaitem.iditem,costo,tipo from salaitem inner join item on salaitem.iditem=item.iditem and tipo='I' and idsala=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		int indexAlquiler=0;
		try { 
			//Obtiene el index para generar el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(queryIndex);
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getInt(1)!=0) {
					indexAlquiler = rs.getInt(1) + 1;
				} else {
					indexAlquiler=1;
				}				
			}
			//Genera el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, indexAlquiler);
			stmt.setString(2,formatoDelTexto.format(alq.getFecha()));  
			stmt.setString(3, alq.getHoraInicio());
			stmt.setString(4, alq.getHoraFin());
			stmt.setInt(5,alq.getUsuario().getIdUsuario());
			stmt.setInt(6, alq.getSala().getIdSala());
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			} else {
				//Genera el detalle del Alquiler
				System.out.println("AlquilerDAO: insertar(Alquiler Detalle)");
				stmt = con.prepareStatement(queryDetalle);
				stmt.setInt(1,alq.getSala().getIdSala());
				rs = stmt.executeQuery();
				while (rs.next()) {
					stmt = con.prepareStatement(queryInsDet);
					stmt.setInt(1, indexAlquiler);
					stmt.setInt(2,rs.getInt(1));  
					stmt.setDouble(3, 0);
					stmt.setString(4, "");
					int k = stmt.executeUpdate();
					if (k != 1) {
						throw new SQLException("No se pudo insertar");
					}
				}
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		if (indexAlquiler!=0){
			return indexAlquiler;
		} else {
			return 0;
		}
	}

	public boolean verificaDisponibilidad(Sala sala,Date fecha, String horaini) throws DAOExcepcion{
		SimpleDateFormat formatoDelTexto = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println("AlquilerDAO: verificarDisponibilidad");
		String query = "select count(idalquiler) from alquiler where idsala=? and fecha=? and horainicio<=? and horafin>=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		boolean verifica=false;
		try { 
			//Obtiene el index para generar el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1,sala.getIdSala());
			stmt.setString(2, formatoDelTexto.format(fecha));
			stmt.setString(3,horaini); 
			stmt.setString(4,horaini); 
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getInt(1)==0) {
					verifica=true;
				} else {
					verifica=false;
				}				
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		if (verifica==true) {
			return true;
		}
		else{
			return false;
		}
	}

	public Item verificaDisponibilidadIns(int idInstrumento, Date fechareserva,
			String horaini) throws DAOExcepcion{
		SimpleDateFormat formatoDelTexto = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println("AlquilerDAO: verificarDisponibilidadIns");
		String query = "select count(iditem) from alquiler inner join detallealquiler on alquiler.idalquiler=detallealquiler.idalquiler and fecha=? and horainicio<=? and horafin>=? and iditem=?";
		String queryItem = "select iditem,costo from item where tipo='I' and iditem=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		boolean verifica=false;
		Item item= new Item();
		try { 
			//Obtiene el index para generar el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, formatoDelTexto.format(fechareserva));
			stmt.setString(2,horaini); 
			stmt.setString(3,horaini);
			stmt.setInt(4,idInstrumento);
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getInt(1)==0) {
					stmt = con.prepareStatement(queryItem);
					stmt.setInt(1,idInstrumento);
					rs = stmt.executeQuery();
					if (rs.next()) {
						if (rs.getInt(1)!=0) {
							item.setIdItem(rs.getInt("idItem"));
							item.setCosto(rs.getDouble("costo"));
							verifica=true;
						} else {
							verifica=false;		
						}				
					}
				} else {
					verifica=false;
				}				
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		if (verifica==true) {
			return item;
		}
		else{
			return null;
		}
	}

	public void agregarInsAdiReserva(DetalleAlquiler detAlq)  throws DAOExcepcion{
		System.out.println("AlquilerDAO: insertar(Alquiler DetalleAdicional)");
		String query = "INSERT INTO detallealquiler(idalquiler,iditem,costo,adicional) VALUES (?,?,?,?)";
		Connection con = null;
		PreparedStatement stmt = null;
		try { 
			//Genera el Detalle Adicional 
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, detAlq.getAlquiler().getIdAlquiler());
			stmt.setInt(2,detAlq.getItem().getIdItem());  
			stmt.setDouble(3, detAlq.getItem().getCosto());
			stmt.setString(4, "A");
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		
	}

	public Item verificaDisponibilidadSer(int indAlquiler, int idServicio)  throws DAOExcepcion{
		System.out.println("AlquilerDAO: verificarDisponibilidadSer");
		String query = "select count(alquiler.idsala) from alquiler inner join salaitem on alquiler.idsala=salaitem.idsala where idalquiler=? and iditem=?";
		String queryItem = "select iditem,costo from item where tipo='S' and iditem=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		boolean verifica=false;
		Item item= new Item();
		try { 
			//Obtiene el index para generar el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, indAlquiler);
			stmt.setInt(2,idServicio); 
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getInt(1)>0) {
					stmt = con.prepareStatement(queryItem);
					stmt.setInt(1,idServicio);
					rs = stmt.executeQuery();
					if (rs.next()) {
						if (rs.getInt(1)!=0) {
							item.setIdItem(rs.getInt("idItem"));
							item.setCosto(rs.getDouble("costo"));
							verifica=true;
						} else {
							verifica=false;		
						}				
					}
				} else {
					verifica=false;
				}				
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		if (verifica==true) {
			return item;
		}
		else{
			return null;
		}
	}

	public Double calcularCostoReserva(int indAlquiler) throws DAOExcepcion{
		System.out.println("AlquilerDAO: calcularCostoAlquiler");
		String queryCostoSala = "select costo from alquiler inner join sala on alquiler.idsala=sala.idsala where idalquiler=?";
		String queryCostoAdi = "select sum(costo) from detallealquiler where adicional='A' and idalquiler=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		Double costo=0.00;
		try { 
			//Obtiene el index para generar el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(queryCostoSala);
			stmt.setInt(1, indAlquiler);
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getDouble(1)>0) {
					costo=costo + rs.getDouble(1); 
				}				
			}
			stmt = con.prepareStatement(queryCostoAdi);
			stmt.setInt(1, indAlquiler);
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getDouble(1)>0) {
					costo=costo + rs.getDouble(1); 
				}				
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return costo;
	}

	public Collection<DetalleAlquiler> obtenerDetalleAlquiler(int indAlquiler) throws DAOExcepcion{
		String queryDetalle = "select D.iditem,descripcion,tipo,D.costo,adicional from detalleAlquiler D inner join item on D.iditem=item.iditem where idAlquiler=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		Collection<DetalleAlquiler> listaDetalleAlquiler = new ArrayList<DetalleAlquiler>();
		try { 
			//Obtiene el index para generar el Alquiler
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(queryDetalle);
			stmt.setInt(1, indAlquiler);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Alquiler Alq=new Alquiler();
				Alq.setIdAlquiler(indAlquiler);
				Item c=new Item();
				c.setIdItem(rs.getInt("iditem"));
				c.setDescripcion(rs.getString( "descripcion"));
				c.setTipo(rs.getString( "tipo"));
				DetalleAlquiler det= new DetalleAlquiler();
				
				det.setAlquiler(Alq);
				det.setItem(c);
				det.setCosto( rs.getDouble( "costo" ) );
				det.setAdicional(rs.getString( "adicional" ));
				listaDetalleAlquiler.add(det);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return listaDetalleAlquiler;
	}

	public Collection<Item> obtenerServicios(int indAlquiler) throws DAOExcepcion{
		String querySala = "select idsala from alquiler where idalquiler=?";
		String queryItem = "select D.iditem,descripcion,costo from salaitem D inner join item T on D.iditem=T.iditem where tipo='S' and idsala=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		Collection<Item> listaServicios = new ArrayList<Item>();
		try { 
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(querySala);
			stmt.setInt(1,indAlquiler);
			rs = stmt.executeQuery();
			if (rs.next()) {
				if (rs.getInt(1)!=0) {
					stmt = con.prepareStatement(queryItem);
					stmt.setInt(1,rs.getInt(1));
					rs = stmt.executeQuery();
					while (rs.next()) {
						Item c=new Item();
						c.setIdItem(rs.getInt("iditem"));
						c.setDescripcion(rs.getString( "descripcion"));
						c.setCosto(rs.getDouble( "costo"));
						listaServicios.add(c);
					}
				}				
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return listaServicios;
	}

	public Collection<Item> obtenerInstrumentosDis() throws DAOExcepcion{
		String queryInstrumento = "select iditem,descripcion,costo from item where tipo='I' and iditem not in(select iditem from salaitem)";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		Collection<Item> listaInstrumento = new ArrayList<Item>();
		try { 
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(queryInstrumento);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Item c=new Item();
				c.setIdItem(rs.getInt("iditem"));
				c.setDescripcion(rs.getString( "descripcion"));
				c.setCosto(rs.getDouble( "costo"));
				listaInstrumento.add(c);
			}
			
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return listaInstrumento;
	}
}
